<template>
  <div>
    <Row :gutter="10">
      <Col :span="4">
        <div class="card-container scroll-container">
          <Form
            :model="formState"
            ref="formRef"
            :label-col="{
              style: {
                width: '220px',
              },
            }"
            layout="vertical"
            :wrapper-col="{ span: 24 }"
            autocomplete="off"
            labelAlign="right"
          >
            <FormItem label="推送方式" name="pushType">
              <Select
                v-model:value="formState.pushType"
                @change="onpushTypeChange"
                :disabled="Boolean(props.configInfo.id)"
              >
                <SelectOption value="1" v-if="pushType === '1'"
                  >项目推送</SelectOption
                >
                <SelectOption value="2" v-if="pushType === '2'"
                  >设备推送</SelectOption
                >
              </Select>
            </FormItem>
            <FormItem
              label="配置编码ID"
              name="configId"
              :rules="[{ required: true, message: '请选择配置编码ID' }]"
            >
              <span
                v-if="!formState.configId"
                class="cursor-pointer underline"
                @click="onConfig"
                >选择版本</span
              >
              <span v-else class="cursor-pointer underline" @click="onConfig">{{
                configData.code
              }}</span>
            </FormItem>
            <FormItem
              label="推送说明"
              name="pushDesc"
              :rules="[{ required: true, message: '请输入推送说明' }]"
            >
              <Textarea v-model:value="formState.pushDesc"></Textarea>
            </FormItem>
          </Form>
          <p>协议版本号</p>
          <span>{{ configData.protobufVersion }}</span>
          <div class="info-item">
            <p class="mt-2">设备类型/型号</p>
            <Tree
              v-if="
                configData.modelAlwaysVOS && configData.modelAlwaysVOS.length
              "
              :tree-data="configData.modelAlwaysVOS"
              :field-names="fileNames"
            />
          </div>
          <p>配置说明</p>
          <span>{{ configData.configExplain }}</span>
        </div>
      </Col>
      <Col :span="20">
        <div class="card-container" v-if="formState.pushType == '2'">
          <Row>
            <Col :span="6">
              <p>项目总数</p>
              <span>{{ statistics.projectNum }}</span></Col
            >
            <Col :span="3">
              <p>已选设备总数</p>
              <span>{{ dataSource.length }}</span></Col
            >
            <Col :span="3" v-for="(item, index) in statistics.typeList">
              <p>{{ item.typeName }}</p>
              <span>{{ item.sum }}</span>
            </Col>
          </Row>
        </div>
        <Row justify="space-between" class="mt-2">
          <Col>
            <div class="table-title">升级计划列表</div>
          </Col>
          <Col>
            <Space>
              <b-button
                icon="add"
                v-if="formState.configId"
                @click="onSelect()"
                >{{
                  formState.pushType == '2' ? '选择设备' : '选择项目'
                }}</b-button
              >
              <b-button v-if="!multiple" icon="delete" @click="onClear()">{{
                formState.pushType == '2' ? '移除设备' : '移除项目'
              }}</b-button>
            </Space>
          </Col>
        </Row>
        <Table
          v-if="formState.pushType == '2'"
          row-key="deviceCode"
          :columns="columnsDevice"
          size="middle"
          :data-source="dataSource"
          :scroll="{ x: 500, y: scrollHeight }"
          :row-selection="rowSelection"
          class="pushType device_table"
        >
        </Table>
        <Table
          v-else
          class="device_table"
          row-key="projectId"
          :columns="columnsProject"
          :scroll="{ x: 500, y: scrollHeight }"
          size="middle"
          :data-source="dataSourceProject"
          :row-selection="rowSelectionProject"
        >
        </Table>
      </Col>
    </Row>
  </div>
  <Modal
    v-model:open="openDevice"
    :title="formState.pushType == '2' ? '选择设备' : '选择项目'"
    :width="1200"
    :mask-closable="false"
    centered
    :footer="null"
    destroy-on-close
  >
    <Device
      v-if="formState.pushType == '2'"
      :row="configData"
      :deviceData="deviceData"
      @pushData="updataData"
    ></Device>
    <Project
      v-else
      :row="configData"
      :deviceData="deviceData"
      @pushData="updataData"
    ></Project>
  </Modal>
  <Modal
    v-model:open="openConfig"
    title="选择版本"
    :width="1200"
    :mask-closable="false"
    centered
    :footer="null"
  >
    <Config @select="onConfigSelect"></Config>
  </Modal>
</template>
<script setup lang="tsx">
import { computed, h, nextTick, onMounted, reactive, ref, watch } from 'vue';
import {
  Col,
  Form,
  FormItem,
  Input,
  Modal,
  Row,
  Select,
  SelectOption,
  Space,
  Table,
  type TableProps,
  Tag,
  Textarea,
  Tree,
  TreeProps,
  message,
} from 'ant-design-vue';
import { ProTable, ProTableProps } from '@/components/ProTable/index';
import { columnWidth, listToEnum } from '@/utils/utils';
import { appUpdateTypeEnum } from '@/constant/push';
import { fetchDictsOfType } from '@/api/dict';
import { getDictType } from '@/api/monitor';
import { saveRecord } from '@/api/notice';
import {
  addQuickConfigTask,
  getDeviceMode,
  getModelStatistics,
  getProjectStatistics,
  updateQuickConfigTask,
} from '@/api/push';
import Config from './Config.vue';
import Device from './Device.vue';
import Project from './Project.vue';

const scrollHeight = ref(0);
onMounted(() => {
  const dom = document.querySelector('.device_table');
  scrollHeight.value = dom?.getBoundingClientRect().height - 40 || 0;
});

const typeEnum: any = ref();
const dictInit = () => {
  getDictType('device_operate_type').then((res) => {
    typeEnum.value = listToEnum(res.data as any, 'dictLabel', 'dictCode');
  });
};

dictInit();

const statistics = ref({
  projectNum: 0,
  typeList: [
    {
      typeName: '预警终端',
      sum: 0,
    },
    {
      typeName: '预警喇叭',
      sum: 0,
    },
    {
      typeName: '桌面终端',
      sum: 0,
    },
  ],
});

const props = defineProps({
  configInfo: {
    type: Object,
    default: {},
  },
  pushType: {
    type: String,
    default: '',
  },
});
console.log(props.configInfo, 'fofngiindi');

watch(
  () => props.configInfo,
  (newVal) => {
    console.log(newVal, '111', '55555555555');
    formState.value.pushType = newVal.pushType;
    formState.value.configId = newVal.configId;
    formState.value.pushDesc = newVal.pushDesc;
    formState.value.id = newVal.id;
    if (props.pushType === '1') {
      if (newVal.projectList) {
        dataSourceProject.value = newVal.projectList;
      } else {
        dataSource.value = newVal.sendDeviceVo;
      }
    } else {
      if (newVal.deviceList) {
        dataSourceProject.value = newVal.deviceList;
      } else {
        dataSource.value = newVal.sendDeviceVo;
      }
    }

    statistics.value = newVal.statistics;
    configData.value = newVal;
    configData.value.typeVOS = newVal.modelAlwaysVOS.map((item: any) => {
      return {
        id: item.modelTypeId,
        name: item.typeName.substring(0, item.typeName.indexOf('(')),
      };
    });
  },
);

interface TableRecord {
  deviceCode: string;
  deviceId: string;
  [key: string]: any;
}
const formRef = ref();
const formState: any = ref({
  pushType: props.pushType,
  configId: '',
  pushDesc: '',
});
const fileNames: TreeProps['fieldNames'] = {
  title: 'typeName',
  children: 'modeName',
};
const modalList = ref<any[]>([]);
const sysDeviceModeEnum = ref<Record<string, any>>({});
onMounted(() => {
  fetchDictsOfType(['sys_device_mode']).then((res: any) => {
    const { sys_device_mode } = res.data;
    sysDeviceModeEnum.value = listToEnum(
      sys_device_mode,
      'dictValue',
      'dictLabel',
    );
  });
  getDeviceMode({}).then((res) => {
    modalList.value = res.data as any;
  });
});
const formatModal = (val: any) => {
  let arr = modalList.value.filter((item) => {
    return item.modelId == val;
  });
  return arr[0]?.model;
};
const rowSelection = computed<ProTableProps['rowSelection']>(() => {
  return {
    selectedRowKeys: selectedRow.value.map((row) => row.deviceCode), // Extract deviceCode for selectedRowKeys
    onChange: (
      selectedRowKeys: (string | number)[],
      selectedRows: TableRecord[],
    ) => {
      handlePushSelection(selectedRowKeys as string[], selectedRows);
    },
    getCheckboxProps: (record: TableRecord) => ({
      deviceCode: record.deviceCode,
      disabled: false,
    }),
  };
});
const rowSelectionProject = computed<ProTableProps['rowSelection']>(() => {
  return {
    selectedRowKeys: selectedRowProject.value.map((row) => row.projectId), // Extract deviceCode for selectedRowKeys
    onChange: (
      selectedRowKeys: (string | number)[],
      selectedRows: TableRecord[],
    ) => {
      handlePushSelectionProject(selectedRowKeys as string[], selectedRows);
    },
    getCheckboxProps: (record: TableRecord) => ({
      projectId: record.projectId,
      disabled: false,
    }),
  };
});
const multiple = ref(true);
const selectedRow = ref<TableRecord[]>([]);
const handlePushSelection = (keys: string[], rows: TableRecord[]) => {
  selectedRow.value = rows;
  multiple.value = !rows.length;
};
const selectedRowProject = ref<TableRecord[]>([]);
const handlePushSelectionProject = (keys: string[], rows: TableRecord[]) => {
  selectedRowProject.value = rows;
  multiple.value = !rows.length;
};
const dataSource = ref<any[]>([]);
const dataSourceProject = ref<any[]>([]);
const columnsDevice = computed<ProTableProps['columns']>(() => [
  {
    title: '所属项目',
    dataIndex: 'shortName',
    align: 'center',
    width: columnWidth('shortName', dataSource.value, '所属项目'),
  },
  {
    title: '设备序列号',
    dataIndex: 'deviceCode',
    align: 'center',
    width: columnWidth('deviceCode', dataSource.value, '设备序列号'),
  },
  {
    title: '软件版本',
    dataIndex: 'softwareVersion',
    align: 'center',
    customRender({ text, record }) {
      return text + (record.versionCode ? `(${record.versionCode})` : '');
    },
    width: columnWidth('softwareVersion', dataSource.value, '所属项目', 20),
  },
  {
    title: '固件版本',
    dataIndex: 'firmwareVersion',
    align: 'center',
    width: columnWidth('firmwareVersion', dataSource.value, '所属项目'),
  },
  {
    title: '设备型号',
    dataIndex: 'modelId',
    align: 'center',
    customRender({ text }) {
      return formatModal(text);
    },
    width: columnWidth('modelId', dataSource.value, '所属项目', 20),
  },
  {
    title: '设备类型',
    dataIndex: 'deviceType',
    align: 'center',
    width: columnWidth('deviceType', dataSource.value, '所属项目'),
    customRender({ text }) {
      return sysDeviceModeEnum.value[text as string];
    },
  },
  {
    title: '地址',
    dataIndex: 'address',
    align: 'center',
    width: columnWidth('address', dataSource.value, '所属项目'),
  },
]);

const columnsProject = computed<ProTableProps['columns']>(() => [
  {
    title: '所属项目',
    dataIndex: 'projectName',
    align: 'center',
    width: columnWidth('projectName', dataSourceProject.value, '所属项目'),
  },
  // {
  //   title: '设备类型/型号',
  //   dataIndex: 'modelAlwaysVOS',
  //   align: 'center',
  //   width: 240,
  //   customRender: ({ record }) => {
  //     const fileNames: TreeProps['fieldNames'] = {
  //       title: 'typeName',
  //       children: 'modeName',
  //     };
  //     return h(Tree, {
  //       treeData: record.modelAlwaysVOS,
  //       fieldNames: fileNames,
  //     });
  //   },
  // },
  {
    title: '设备总数',
    dataIndex: 'count',
    align: 'center',
    width: columnWidth('count', dataSourceProject.value, '所属项目'),
  },
  {
    title: '项目说明',
    dataIndex: 'projectRemark',
    align: 'center',
    width: columnWidth('projectRemark', dataSourceProject.value, '所属项目'),
  },
]);
const onpushTypeChange = () => {
  dataSource.value = [];
  dataSourceProject.value = [];
};
const deviceData = ref<any[]>([]);
const openDevice = ref(false);
const onSelect = () => {
  deviceData.value = [];
  openDevice.value = true;
  nextTick(() => {
    if (formState.value.pushType == '2') {
      deviceData.value = JSON.parse(JSON.stringify(dataSource.value));
    } else {
      deviceData.value = JSON.parse(JSON.stringify(dataSourceProject.value));
    }
  });

  console.log(
    formState.value.pushType,
    deviceData.value,
    'formState.value.pushType',
  );
};

const getDeviceStatistics = (list: any) => {
  console.log(list);
  let _arr = [];
  if (formState.value.pushType == '2') {
    _arr = list.map((item) => {
      return item.deviceId;
    });
    getModelStatistics(_arr.join(',')).then((res) => {
      console.log(res, 'res');
      statistics.value = res.data as any;
    });
  } else {
    _arr = list.map((item) => {
      return item.projectId;
    });
    getProjectStatistics({ projectIds: _arr.join(',') }).then((res) => {
      console.log(res, 'res');
      statistics.value = res.data as any;
    });
  }
};
const updataData = (data: any) => {
  if (formState.value.pushType == '2') {
    dataSource.value = data;
    getDeviceStatistics(dataSource.value);
  } else {
    dataSourceProject.value = data;
    getDeviceStatistics(dataSourceProject.value);
  }
};

const onClear = () => {
  if (formState.value.pushType == '2') {
    for (let i = 0; i < selectedRow.value.length; i++) {
      for (let j = 0; j < dataSource.value.length; j++) {
        if (
          selectedRow.value[i].deviceCode === dataSource.value[j].deviceCode &&
          selectedRow.value[i].deviceId === dataSource.value[j].deviceId
        ) {
          dataSource.value.splice(j, 1);
        }
      }
    }
    if (rowSelection.value && rowSelection.value.onChange) {
      rowSelection.value.onChange([], []);
    }
  } else {
    for (let i = 0; i < selectedRowProject.value.length; i++) {
      for (let j = 0; j < dataSourceProject.value.length; j++) {
        if (
          selectedRowProject.value[i].projectId ===
          dataSourceProject.value[j].projectId
        ) {
          dataSourceProject.value.splice(j, 1);
        }
      }
    }
    if (rowSelectionProject.value && rowSelectionProject.value.onChange) {
      rowSelectionProject.value.onChange([], []);
    }
  }
};

const openConfig = ref(false);
const onConfig = () => {
  openConfig.value = true;
};

const configData = ref<any>({});
const onConfigSelect = (record: any) => {
  configData.value = record;
  formState.value.configId = record.id;
  configData.value.typeVOS = configData.value.modelAlwaysVOS.map(
    (item: any) => {
      return {
        id: item.modelTypeId,
        name: item.typeName.substring(0, item.typeName.indexOf('(')),
      };
    },
  );
  console.log(configData.value, 'configData.value');
  openConfig.value = false;
};

const emit = defineEmits(['pushUpdate', 'versionUpdate']);
async function submitForm() {
  let _data = [];
  if (formState.value.pushType == '2') {
    _data = dataSource.value;
  } else {
    _data = dataSourceProject.value;
  }
  let text = `推送列表不能为空，请选择${formState.value.pushType == '2' ? '设备' : '项目'}`;
  if (_data.length == 0) return message.error(text);

  formRef.value
    .validate()
    .then(async () => {
      console.log(configData.value, 'dataSourceProject.value');

      let _arr = [];
      let params = {};
      if (formState.value.pushType == '2') {
        _arr = dataSource.value.map((item) => {
          return item.deviceId;
        });
        params = {
          deviceIds: _arr,
        };
      } else {
        _arr = dataSourceProject.value.map((item) => {
          return item.projectId;
        });
        params = {
          projectIds: _arr,
          modelIds: configData.value.modelIds,
        };
      }

      console.log(formState.value, params, 'formState.value');
      let res: any;
      if (!formState.value.id) {
        res = await addQuickConfigTask({
          ...formState.value,
          ...params,
        });
        message.success('新增成功');
        emit('versionUpdate', true);
      } else {
        res = await updateQuickConfigTask({
          ...formState.value,
          ...params,
        });
        message.success('修改成功');
        emit('versionUpdate', true);
      }
      ({ ...formState.value, ...params });
      let operateUri = !formState.value.id
        ? '/quickConfigTask/add'
        : '/quickConfigTask/update';
      saveRecordFn(
        configData.value,
        res,
        '推送',
        JSON.stringify({
          ...formState.value,
          ...params,
        }),
        operateUri,
      );
    })
    .catch((error) => {
      console.log('error', error);
    });
}

const saveRecordFn = async (
  item: any,
  res: any,
  operateButton: any,
  requestParam: any,
  operateUri: string,
) => {
  const list = [
    {
      deviceCode: item.code,
      operateModule: '推送管理/项目推送任务',
      requestParam,
      status: res.code == 200 ? 1 : 0,
      operateButton,
      operateType: typeEnum.value[operateButton],
      operateUri,
    },
  ];
  await saveRecord({ list });
};

defineExpose({
  submitForm,
});
</script>
<style lang="scss" scoped>
.scroll-container {
  height: 63vh;
  overflow-y: auto;
  p {
    position: relative;
    color: #fff;
    &::before {
      position: absolute;
      left: -8px;
      top: 50%;
      transform: translateY(-50%);
      content: '';
      width: 2px;
      height: 12px;
      background-color: #1890ff;
    }
  }
}
.underline {
  text-underline-offset: 5px;
  &:hover {
    color: #1890ff;
  }
}

:deep(.line) {
  text-decoration: underline;
}
.table-title {
  height: 4vh;
  line-height: 4vh;
  font-size: 16px;
  font-weight: bold;
  color: #fff;
}
:deep(.ant-table) {
  height: calc(60vh - 85px);
}
:deep(.ant-table-body) {
  height: calc(60vh - 125px);
}
.pushType {
  :deep(.ant-table) {
    height: calc(60vh - 177px);
  }
  :deep(.ant-table-body) {
    height: calc(60vh - 217px);
  }
}
:deep(.ant-tree) {
  background: none;
}
</style>
